package com.wwdx.service.impl;

import com.google.common.collect.Lists;
import com.wwdx.BaseCommons;
import com.wwdx.model.WwdxBookModel;
import com.wwdx.model.WwdxVipUserModel;
import com.wwdx.model.WwdxWeixinUserModel;
import com.wwdx.service.TemplateMsgTaskServiceI;
import com.wwdx.utils.ConstantHolder;
import com.wwdx.wechat.WxConstant;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author liguoliang
 * @date 2018-03-12 16:21
 */
@Service
public class TemplateMsgTaskServiceImpl extends BaseCommons implements TemplateMsgTaskServiceI{

    @Override
    public void sendVipExpiresTemplate(){
        logger.info("会员过期通知");
        String appId = miDuWxService.getWxMpConfigStorage().getAppId();
        List<WwdxVipUserModel> wwdxVipUserModels = wwdxVipUserService.find("from WwdxVipUserModel");
        int count = 0;
        for (WwdxVipUserModel wwdxVipUserModel : wwdxVipUserModels) {
            String unionid = wwdxVipUserModel.getUnionid();
            WwdxWeixinUserModel wwdxWeixinUserModel = wwdxWeixinUserService.getByUnionId(appId,unionid);
            if (wwdxWeixinUserModel != null) {
                String openId = wwdxWeixinUserModel.getOpenid(),nickname = wwdxWeixinUserModel.getNickname(),
                                expireTime = wwdxVipUserModel.getExpire_time();
                int days = Days.daysBetween(new LocalDate(expireTime),new LocalDate()).getDays();
                ArrayList<String> list = Lists.newArrayList(wwdxVipUserModel.getEffect_time(),expireTime);
                TemplateMsgDTO model = TemplateMsgDTO.builder()
                        .keywords(list).templateId(WxConstant.TEMPLATE_VIP_EXPIRE).openid(openId).build();
                String url,frist,remark;
                //过期前一天提醒
                if (days == -1) {
                    frist = "亲爱的" + nickname + "，你的蜜读VIP听书卡即将过期。\n" +
                            "立即续费，继续与1%的终身学习者一起读书，让读书成为我们最好的老师，用阅读改写人生。\n";
                    remark = "↓↓点击“详情”，邀请好友！";
                    url = wechatUrl+"auth.html?url="+URIUtil.encodeURIComponent(wechatUrl+"memberPage.html?showInviteMask=1");
                    this.execute(miDuWxService,model,frist,remark,url);
                    count ++;
                }
            }
        }
        logger.info("会员过期通知,受影响行数：{}",count);
    }

    /**
     * 会员学习计划通知
     */
    @Override
    public void sendVipPlanTemplate(Long bookid,Integer phase){
        logger.info("会员学习计划通知");
        int count = 0;
        WwdxBookModel wwdxBookModel = wwdxBookService.getByBookId(bookid);
        String bookSummary = wwdxBookModel.getContentsummary(),bookname = wwdxBookModel.getBookname();
        String appId = miDuWxService.getWxMpConfigStorage().getAppId();
        //会员用户
        List<WwdxVipUserModel> wwdxVipUserModels = wwdxVipUserService.find("from WwdxVipUserModel where subscribe=1");
        for (WwdxVipUserModel wwdxVipUserModel : wwdxVipUserModels) {
            String unionid = wwdxVipUserModel.getUnionid();
            WwdxWeixinUserModel wwdxWeixinUserModel = wwdxWeixinUserService.getByUnionId(appId,unionid);
            if (wwdxWeixinUserModel != null) {
                this.execute(wwdxWeixinUserModel.getOpenid(),bookSummary,bookname,phase);
                count ++;
            }
        }
        logger.info("会员学习计划通知,受影响行数：{}",count);
    }

    /**
     * 首页订阅用户
     */
    @Override
    public void sendSubscribeTemplate(Long bookid,Integer phase){
        logger.info("首页订阅用户通知");
        int count = 0;
        //首页订阅用户
        WwdxBookModel wwdxBookModel = wwdxBookService.getByBookId(bookid);
        String bookSummary = wwdxBookModel.getContentsummary(),bookname = wwdxBookModel.getBookname();
        String appId = miDuWxService.getWxMpConfigStorage().getAppId();
        Set<Object> members = setOperations.members(ConstantHolder.USER_SUBSCRIBE_TOTAL_SET);
        if (!CollectionUtils.isEmpty(members)){
            for (Object member : members) {
                WwdxWeixinUserModel wwdxWeixinUserModel = wwdxWeixinUserService.getByUnionId(appId, member.toString());
                if (wwdxWeixinUserModel != null){
                    this.execute(wwdxWeixinUserModel.getOpenid(),bookSummary,bookname,phase);
                    count ++;
                }
            }
        }
        logger.info("首页订阅用户通知,受影响行数：{}",count);
    }

    private synchronized void execute(String openId,String bookSummary,String bookname,int phase){
        String studyTime = new LocalDate().toString();
        ArrayList<String> list = Lists.newArrayList("蜜读听书为您解读第"+(100+phase)+"本书",studyTime);
        TemplateMsgDTO model = TemplateMsgDTO.builder()
                .keywords(list).templateId(WxConstant.TEMPLATE_VIP_PLAN).openid(openId).build();
        String frist = "晨听一本书，高效一整天，今日听书推荐：\n" +
                "《"+bookname+"》\n" + bookSummary+"\n";
        String remark = "一天一本书，碎片化时间，高效学习。\n" +
                "回复“TD”退订每日听书提醒，回复“DY”恢复提醒。";
        this.execute(miDuWxService,model,frist,remark,wechatUrl+"auth.html");
    }

    private void execute(WxMpService service, TemplateMsgDTO model, String frist, String remark, String url){
        model.setFrist(frist);
        model.setRemark(remark);
        model.setUrl(url);
        this.sendTemplate(service,model);
    }
    
    private void sendTemplate(WxMpService service,TemplateMsgDTO model){
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .templateId(model.getTemplateId()).url(model.getUrl()).toUser(model.getOpenid()).build();
        WxMpTemplateData firstData = new WxMpTemplateData("first", model.getFrist(),"#d43f3a");
        WxMpTemplateData remarkData = new WxMpTemplateData("remark", "\n"+model.getRemark(),"#576b95");
        templateMessage.addData(firstData).addData(remarkData);
        List<String> keywords = model.getKeywords();
        for (int i = 0; i < keywords.size(); i++) {
            WxMpTemplateData data = new WxMpTemplateData("keyword"+(i+1), keywords.get(i));
            templateMessage.addData(data);
        }
        try{
            service.getTemplateMsgService().sendTemplateMsg(templateMessage);
        }catch (WxErrorException e){
            logger.error("错误信息：{}",e.getMessage());
        }
    }

    @Override
    public void sendGiveOneTemplate(String appId,String unionid,String unionid2,Long bookid) {
        String dateTime = new DateTime().toString("yyyy年MM月dd日 HH:mm");
        WwdxBookModel wwdxBookModel = wwdxBookService.getByBookId(bookid);
        String openid = wwdxWeixinUserService.getByUnionId(appId, unionid).getOpenid();
        String nickname = wwdxWeixinUserService.getByUnionId(appId, unionid2).getNickname();
        ArrayList<String> list = Lists.newArrayList("好友助力免费听书",dateTime,
                "恭喜你和好友"+nickname+"共同获得《"+wwdxBookModel.getBookname()+"》");
        TemplateMsgDTO model = TemplateMsgDTO.builder()
                .keywords(list).templateId(WxConstant.TEMPLATE_GIVEONE).openid(openid).build();
        String remark = "点此开始听书";
        String url = URIUtil.encodeURIComponent(wechatUrl+String.format(WxConstant.SINGLEBOOK_PAGE,bookid,
                wwdxBookModel.getVideoauthorid(),wwdxBookModel.getCopywriter()));
        this.execute(miDuWxService,model,"",remark,wechatUrl+"auth.html?url="+url);
    }

    /**
     * @author liguoliang
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    private static class TemplateMsgDTO implements Serializable {
        private String templateId;
        private String frist;
        private String remark;
        private String openid;
        private String url;
        private List<String> keywords;
    }
}